package engineio

import (
	"io"
	"sync"

	"go-share/googollee/go-engine.io/parser"
)

type connReader struct {
	*parser.PacketDecoder
	closeChan chan struct{}
}

func newConnReader(d *parser.PacketDecoder, closeChan chan struct{}) *connReader {
	return &connReader{
		PacketDecoder: d,
		closeChan:     closeChan,
	}
}

func (r *connReader) Close() error {
	if r.closeChan == nil {
		return nil
	}
	r.closeChan <- struct{}{}
	r.closeChan = nil
	return nil
}

type connWriter struct {
	io.WriteCloser
	locker *sync.Mutex
}

func newConnWriter(w io.WriteCloser, locker *sync.Mutex) *connWriter {
	return &connWriter{
		WriteCloser: w,
		locker:      locker,
	}
}

func (w *connWriter) Close() error {
	defer func() {
		if w.locker != nil {
			w.locker.Unlock()
			w.locker = nil
		}
	}()
	return w.WriteCloser.Close()
}

// Copy copies from src to dst until either EOF is reached
// on src or an error occurs.  It returns the number of bytes
// copied and the first error encountered while copying, if any.
//
// A successful Copy returns err == nil, not err == EOF.
// Because Copy is defined to read from src until EOF, it does
// not treat an EOF from Read as an error to be reported.
//
// If src implements the WriterTo interface,
// the copy is implemented by calling src.WriteTo(dst).
// Otherwise, if dst implements the ReaderFrom interface,
// the copy is implemented by calling dst.ReadFrom(src).
// func Copy(dst io.Writer, src io.Reader) (written int64, err error) {
// 	return copyBuffer(dst, src, nil)
// }

// CopyBuffer is identical to Copy except that it stages through the
// provided buffer (if one is required) rather than allocating a
// temporary one. If buf is nil, one is allocated; otherwise if it has
// zero length, CopyBuffer panics.
// func CopyBuffer(dst io.Writer, src io.Reader, buf []byte) (written int64, err error) {
// 	if buf != nil && len(buf) == 0 {
// 		panic("empty buffer in io.CopyBuffer")
// 	}
// 	return copyBuffer(dst, src, buf)
// }

// copyBuffer is the actual implementation of Copy and CopyBuffer.
// if buf is nil, one is allocated.
// func copyBuffer(dst io.Writer, src io.Reader, buf []byte) (written int64, err error) {
// 	// If the reader has a WriteTo method, use it to do the copy.
// 	// Avoids an allocation and a copy.
// 	if wt, ok := src.(io.WriterTo); ok {
// 		return wt.WriteTo(dst)
// 	}
// 	// Similarly, if the writer has a ReadFrom method, use it to do the copy.
// 	if rt, ok := dst.(io.ReaderFrom); ok {
// 		return rt.ReadFrom(src)
// 	}
// 	if buf == nil {
// 		buf = make([]byte, 32*1024)
// 	}
// 	for {
// 		nr, er := src.Read(buf)
// 		if nr > 0 {
// 			nw, ew := dst.Write(buf[0:nr])
// 			if nw > 0 {
// 				written += int64(nw)
// 			}
// 			if ew != nil {
// 				err = ew
// 				break
// 			}
// 			if nr != nw {
// 				err = io.ErrShortWrite
// 				break
// 			}
// 		}
// 		if er == io.EOF {
// 			break
// 		}
// 		if er != nil {
// 			err = er
// 			break
// 		}
// 	}
// 	return written, err
// }
